// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "volatile_nvram.h"

#include <base/logging.h>

namespace tpmd {

VolatileNvram::VolatileNvram() {
  for (unsigned int i = 0; i < MAX_SLOTS; i++)
    slots_[i].bytes_.clear();
}

VolatileNvram::~VolatileNvram() {}

bool VolatileNvram::Allocate(uint32_t slot, size_t size, uint32_t flags) {
  slot -= NVRAM_BASE;
  if (slot >= MAX_SLOTS || size == 0 || slots_[slot].bytes_.size() != 0) {
    return false;
  }
  slots_[slot].bytes_.resize(size);
  memset(&slots_[slot].bytes_[0], 0, size);
  if (flags & NVRAM_LOCKONCE)
    slots_[slot].lockonce_ = true;
  slots_[slot].locked_ = false;
  slots_[slot].defined_ = false;
  return true;
}

bool VolatileNvram::Free(uint32_t slot) {
  slot -= NVRAM_BASE;
  if (slot >= MAX_SLOTS || slots_[slot].bytes_.size() == 0)
    return false;
  slots_[slot].bytes_.clear();
  return true;
}

bool VolatileNvram::Write(uint32_t slot, const Bytes& bytes) {
  slot -= NVRAM_BASE;
  if (slot >= MAX_SLOTS || slots_[slot].bytes_.size() != bytes.size())
    return false;
  if (slots_[slot].locked_)
    return false;
  memcpy(&slots_[slot].bytes_[0], &bytes[0], bytes.size());
  if (slots_[slot].lockonce_ && !slots_[slot].defined_)
    slots_[slot].locked_ = true;
  slots_[slot].defined_ = true;
  return true;
}

bool VolatileNvram::Read(uint32_t slot, Bytes* bytes) {
  slot -= NVRAM_BASE;
  if (slot >= MAX_SLOTS || slots_[slot].bytes_.size() == 0)
    return false;
  if (!slots_[slot].defined_)
    return false;
  bytes->resize(slots_[slot].bytes_.size());
  memcpy(&bytes->at(0), &slots_[slot].bytes_[0], bytes->size());
  return true;
}

bool VolatileNvram::is_defined(uint32_t slot) {
  slot -= NVRAM_BASE;
  if (slot >= MAX_SLOTS)
    return false;
  return slots_[slot].defined_;
}

bool VolatileNvram::is_locked(uint32_t slot) {
  slot -= NVRAM_BASE;
  if (slot >= MAX_SLOTS)
    return false;
  return slots_[slot].locked_;
}

size_t VolatileNvram::size(uint32_t slot) {
  slot -= NVRAM_BASE;
  if (slot >= MAX_SLOTS)
    return 0;
  return slots_[slot].bytes_.size();
}

size_t VolatileNvram::num_slots() {
  return VolatileNvram::MAX_SLOTS;
}

}  // namespace tpmd
